//
//  DMLParallaxHeader.m
//  DMLParallaxHeader
//
//  Created by 戴明亮 on 2017/9/7.
//  Copyright © 2017年 DML. All rights reserved.
//

#import <objc/runtime.h>
#import "DMLParallaxHeader.h"


@interface DMLParallaxView : UIView
@property (nonatomic, weak) DMLParallaxHeader *parent;
@end

@implementation DMLParallaxView

static void * const kDMLParallaxHeaderKVOContext = (void*)&kDMLParallaxHeaderKVOContext;

- (void)willMoveToSuperview:(UIView *)newSuperview
{
    if ([self.superview isKindOfClass:[UIScrollView class]]) {
        [self.superview removeObserver:self.parent forKeyPath:NSStringFromSelector(@selector(contentOffset)) context:kDMLParallaxHeaderKVOContext];
    }
}


- (void)didMoveToSuperview
{
    
    if ([self.superview isKindOfClass:[UIScrollView class]]) {
        [self.superview addObserver:self.parent forKeyPath:NSStringFromSelector(@selector(contentOffset)) options:NSKeyValueObservingOptionNew context:kDMLParallaxHeaderKVOContext];
    }
}



@end


@interface DMLParallaxHeader ()

@property (nonatomic, strong) UIScrollView *scrollView;
@end



@implementation DMLParallaxHeader{
    BOOL _isObserving;
}

@synthesize contentView = _contentView;



- (UIView *)contentView
{
    if (_contentView == nil) {
        DMLParallaxView *contenView = [[DMLParallaxView alloc] init];
        
        contenView.parent = self;
        contenView.clipsToBounds = YES;
        _contentView = contenView;
        contenView.backgroundColor = [UIColor redColor];
    }
    return _contentView;
}


- (void)setView:(UIView *)view
{
    if (view != _view) {
        _view = view;
        [self updateConstraints];
    }
}



- (void)setHeight:(CGFloat)height
{
    if (_height != height) {
        [ self adjustScrollViewTopInset:self.scrollView.contentInset.top - _height + height];
        _height = height;
        [self updateConstraints];
        [self layoutContentView];
    }
}

- (void)setMinimumHeight:(CGFloat)minimumHeight
{
    _minimumHeight = minimumHeight;
    [self layoutContentView];
}

- (void)setScrollView:(UIScrollView *)scrollView
{
    if (_scrollView != scrollView) {
        _scrollView = scrollView;
        [self adjustScrollViewTopInset:scrollView.contentInset.top + self.height];
        [scrollView addSubview:self.contentView];
        
        [self layoutContentView];
        _isObserving = YES;
    }
    
}



- (void)setProgress:(CGFloat)progress
{
    if (_progress != progress) {
        _progress = progress;
        if ([_delegate respondsToSelector:@selector(parallaxHeaderDidScroll:)]) {
            [_delegate parallaxHeaderDidScroll:self];
        }
    }
}









#pragma mark Private Methods
// 更新约束
- (void)updateConstraints
{
    
    
    if (self.view == nil) {
        return;
    }
    
    [self.view removeFromSuperview];
    [self.contentView addSubview:self.view];
    self.view.translatesAutoresizingMaskIntoConstraints = NO;

    
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
    
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeHeight multiplier:1 constant:0]];
    
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
    
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
    
    
    
}


// 根据偏移量调整头部视图的frame
- (void)layoutContentView
{
    
    CGFloat minimumHeight = MIN(self.minimumHeight, self.height);
    CGFloat relativeYOffset = self.scrollView.contentOffset.y + self.scrollView.contentInset.top - self.height;
    CGFloat relativeHeight = -relativeYOffset;
    
    CGRect frame = (CGRect){
        .origin.x = 0,
        .origin.y =relativeYOffset,
        .size.width = self.scrollView.frame.size.width,
        .size.height = MAX(relativeHeight, minimumHeight)
    };
    
    self.contentView.frame =frame;
    
    CGFloat div = self.height - self.minimumHeight;
    
    self.progress = (self.contentView.frame.size.height - self.minimumHeight) / (div ? : self.height);
    
}


// 调整外界scrollview的偏移量
- (void)adjustScrollViewTopInset:(CGFloat)top
{
    UIEdgeInsets inset = self.scrollView.contentInset;
    
    
    // 调整 偏移量
    CGPoint offset = self.scrollView.contentOffset;
    offset.y += inset.top - top;
    self.scrollView.contentOffset = offset;
    // 调整内边距
    inset.top = top;
    self.scrollView.contentInset = inset;
    
    
    
}


#pragma mark KVO

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    if (context == kDMLParallaxHeaderKVOContext) {
        if ([keyPath isEqualToString:NSStringFromSelector(@selector(contentOffset))]) {
            [self layoutContentView];
        }
        
    }else{
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}


@end


@implementation UIScrollView (DMLParallaxHeader)
// 设置关联属性
- (DMLParallaxHeader *)parallaxHeader
{
    DMLParallaxHeader *parallaxHeader = objc_getAssociatedObject(self, @selector(parallaxHeader));
    if (!parallaxHeader) {
        parallaxHeader = [[DMLParallaxHeader alloc] init];
        [self setParallaxHeader:parallaxHeader];
    }
    
    return parallaxHeader;
    
}



- (void)setParallaxHeader:(DMLParallaxHeader *)parallaxHeader
{
    // 将外界的scrollview 进行赋值
    parallaxHeader.scrollView = self;
    objc_setAssociatedObject(self, @selector(parallaxHeader), parallaxHeader, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
}

@end




